package com.liaoye.hellocustomview.view;

import android.content.Context;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.CameraProfile;
import android.media.MediaRecorder;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.liaoye.hellocustomview.CustomViewActivity;
import com.liaoye.hellocustomview.util.FileUtil;

import java.io.IOException;
import java.util.List;

public class CameraPreSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
    private Context mContext;
    private Camera mCamera;
    private SurfaceHolder mHolder;
    private int mCameraId;
    private int mCameraFace = Camera.CameraInfo.CAMERA_FACING_BACK;

    private static final String TAG = CameraPreSurfaceView.class.getSimpleName();
    private MediaRecorder mMediaRecorder;


    public CameraPreSurfaceView(Context context) {
        super(context);
        mContext = context;
        initCamera();
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    private void initCamera() {
        try {
            int numberOfCameras = Camera.getNumberOfCameras();
            Log.i(TAG, "initCamera: numberOfCameras= " + numberOfCameras);
            Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
            for (int i = 0; i < numberOfCameras; i++) {
                Camera.getCameraInfo(i, cameraInfo);
                if(cameraInfo.facing == mCameraFace){
                    mCameraId = i;
                    break;
                }
            }
            mCamera = Camera.open(mCameraId);
        } catch (Exception e) {
            Log.i(TAG, "getCameraInstance: " + e.getMessage());
        }
    }


    @Override
    public void surfaceCreated(@NonNull SurfaceHolder holder) {
        Log.i(TAG, "surfaceCreated: ");
        startCameraPreview();
    }

    private void startCameraPreview() {
        try {
            Camera.Parameters parameters = mCamera.getParameters();

            List<Camera.Size> localSizes = mCamera.getParameters().getSupportedPreviewSizes();
            for (int i = 0; i < localSizes.size(); i++) {
                Log.i(TAG, "surfaceCreated:  width = " + localSizes.get(i).width + " height= " + localSizes.get(i).height);
            }
            parameters.setPreviewFpsRange(10, 20);
            if(!localSizes.isEmpty()){
                Camera.Size cameraSize = localSizes.get(0);
                parameters.setPreviewSize(cameraSize.width, cameraSize.height);
            }
            if(mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
//                parameters.set("orientation", "portrait");
//                parameters.setRotation(90);
                mCamera.setDisplayOrientation(90);
            } else {
//                parameters.set("orientation", "portrait");
//                parameters.setRotation(0);
                mCamera.setDisplayOrientation(0);
            }

            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
        Log.i(TAG, "surfaceChanged: ");
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.
        if(mHolder.getSurface() == null) {
            // stop preview before making changes
            return;
        }
        try {
            mCamera.stopPreview();
        } catch (Exception e) {
            // ignore: tried to stop a non-existent preview
        }

        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
            Log.d(TAG, "Error starting  camera preview: " + e.getMessage());
        }
    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
        Log.i(TAG, "surfaceDestroyed: ");
        stopPreviewAndFreeCamera();
    }


    private void stopPreviewAndFreeCamera() {
        if (mCamera != null) {
            // Call stopPreview() to stop updating the preview surface.
            mCamera.stopPreview();

            // Important: Call release() to release the camera for use by other
            // applications. Applications should release the camera immediately
            // during onPause() and re-open() it during onResume()).
            mCamera.release();
            mCamera = null;
        }
    }


    public void switchCamera(){
       stopPreviewAndFreeCamera();
       mCameraFace = mCameraFace == Camera.CameraInfo.CAMERA_FACING_BACK ? Camera.CameraInfo.CAMERA_FACING_FRONT : Camera.CameraInfo.CAMERA_FACING_BACK;
       initCamera();
       startCameraPreview();
    }


    public void takePicture() {
        mCamera.takePicture(null, null, new Camera.PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                boolean isSuccess = FileUtil.saveCameraPicture(data);
                if(isSuccess) {
                    Toast.makeText(mContext, "拍照并且保存成功", Toast.LENGTH_LONG).show();
                }
                postDelayed(()->{
                    startCameraPreview();
                },3000);
            }
        });
    }


    //解锁相机 - 通过调用 Camera.unlock() 解锁相机以供 MediaRecorder 使用
    public boolean capture() {
        //1.解锁相机
        mCamera.unlock();

        //2.配置 MediaRecorder
        mMediaRecorder = new MediaRecorder();
        //2.1 设置要用于视频捕获的相机
        mMediaRecorder.setCamera(mCamera);

        //2.2 设置音频源
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        //2.3 设置视频源
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

        //2.4 设置视频的输出格式和编码
        mMediaRecorder.setProfile(CamcorderProfile.get(CameraProfile.QUALITY_HIGH));

        //2.5 设置输出文件
        mMediaRecorder.setOutputFile(FileUtil.getOutputMediaFile(FileUtil.MEDIA_TYPE_VIDEO).toString());

        //2.6 为您的应用指定 SurfaceView 预览布局元素
        mMediaRecorder.setPreviewDisplay(mHolder.getSurface());

        mMediaRecorder.setOrientationHint(270);


        try {
            //3.准备 MediaRecorder
            mMediaRecorder.prepare();

            //4.启动 MediaRecorder
            mMediaRecorder.start();

        } catch (IOException e) {
            e.printStackTrace();
            releaseMediaRecorder();
            return false;
        }

        return true;
    }


    public void releaseMediaRecorder(){
        if (mMediaRecorder != null) {
            //1.停止 MediaRecorder
            mMediaRecorder.stop();

            //2.重置 MediaRecorder
            mMediaRecorder.reset();   // clear recorder configuration

            //3.释放 MediaRecorder
            mMediaRecorder.release(); // release the recorder object
            mMediaRecorder = null;

            //4.锁定相机
            mCamera.lock();           // lock camera for later use
        }
    }

}
